package com.zyl.Ecs.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @version v1.0
 * @ProjectName: Ecs
 * @Package: com.zyl.Ecs.common.utils
 * @ClassName: CUtil
 * @Description TODO (一般工具类)
 * @Author 翟玉龙
 * @Date 2024/12/4-11:17
 */
public class CUtil {
    private static final Logger log = LoggerFactory.getLogger(CUtil.class);

    /**
     * 将log的各种用法进行封装
     */
    public static void logInfo(String msg) {
        log.info(msg);
    }

    public static void logError(String msg) {
        log.error(msg);
    }

    public static void logDebug(String msg) {
        log.debug(msg);
    }

    public static void logWarn(String msg) {
        log.warn(msg);
    }


    /**
     * @Author zyl
     * @Description  bean--->vo（单个对象的转换）
     * @version: v1.0
     * @Param source：原本的bean对象，clazz：vo的类对象
     * @return V：赋值以后的的vo对象
     **/
    public static <V> V copyBean(Object source, Class<V> clazz) {
        V target;
        try {
            // 获取默认构造函数并创建目标对象
            Constructor<V> constructor = clazz.getDeclaredConstructor();

            if (!constructor.isAccessible()) {
                constructor.setAccessible(true);
            }
            target = constructor.newInstance();
            // 实现属性拷贝
            BeanUtils.copyProperties(source, target);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        // 返回目标对象
        return target;
    }


    /**
     * @Author zyl
     * @Description  bean--->vo（多个对象的转换）
     * @version: v1.0
     * @Param sourceList：原本存放bean对象的集合，clazz：vo的类对象
     * @return List<V>：复制以后的存放vo对象的集合
     **/
    public static <S,V> List<V> copyBeanList(List<S> sourceList, Class<V> clazz){
        //返回vo的list集合
        return sourceList.stream()
                .map(source -> copyBean(source,clazz))
                .collect(Collectors.toList());
    }

    /**
     * 使用 SHA-256 算法加密密码。
     *
     * @param password 要加密的原始密码字符串
     * @return 加密后的密码字符串
     */
    public static String encrypt(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hashedBytes = md.digest(password.getBytes());

            // 将字节数组转换为十六进制表示的字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : hashedBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();

        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("无法找到 SHA-256 算法实现", e);
        }
    }


    /**
     * 生成唯一键
     *
     * @param data  数据
     * @param width 宽度
     * @param height 高度
     * @return 唯一键
     */
    private static String generateUniqueKey(Object data, int width, int height) {
        return data.toString() + "_" + width + "_" + height;
    }

    /**
     * 格式化当前时间
     * @return {@link String }
     */
    public static String formatLocalDateTime() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 使用formatter将now转换为指定格式的字符串
        return now.format(formatter);
    }

    /**
     * 生成随机的UUID
     * @return {@link String }
     */
    public static String UUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 将List<Map<String, Object>> 转化为泛型Map<String, <T>> 或者对象类
     * 用于基本键值映射关联到指定对象中
     * @param list 列表
     * @param key 键
     * @param clazz 值类型
     * @return Map<String, T>
     * @param <T> 泛型
     */
    public static <T> Map<String, T> listToMapObject(List<Map<String, Object>> list, String key, Class<T> clazz) {
        // 类型转换检查
        if (!clazz.isInstance(list.get(0).get(key))) {
            logInfo("类型转换错误");
            throw new RuntimeException("类型转换错误");
        }
        return list.stream()
                .collect(Collectors.toMap(
                        item -> String.valueOf(item.get(key)),
                        item -> clazz.cast(item.get(key)),
                        (existingValue, newValue) -> existingValue
                ));
    }

    /**
     * 将List<Map<String, Object>> 转化为泛型Map<String, <T>>
     * 用于拆开Map列表
     * @param list 列表
     * @param keyField 键字段
     * @param valueField 值字段
     * @return Map<String, T>
     * @param <T> 泛型
     */
    public static <T> Map<String, T> listToMap(List<Map<String, Object>> list, String keyField, String valueField, Class<T> clazz) {
        // 检查列表是否为空或为空集合
        if (list == null || list.isEmpty()) {
            return Collections.emptyMap();
        }

        // 类型转换检查
        for (Map<String, Object> item : list) {
            if (!CUtil.isInteger(item.get(valueField))) {
                logInfo("类型转换错误");
                throw new IllegalArgumentException("类型转换错误");
            }
        }

        // 转换并收集结果
        return list.stream()
                .collect(Collectors.toMap(
                        item -> String.valueOf(item.get(keyField)),
                        item -> clazz.cast(item.get(valueField)),
                        (existingValue, newValue) -> existingValue
                ));
    }


    /**
     * 判断是否为整数
     * @param o 对象
     * @return boolean
     */
    private static boolean isInteger(Object o) {
        try {
            Integer.parseInt(o.toString());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static void CommonException() {
        RuntimeException e = new RuntimeException("当前没有用户登录!");
        logError("获取token失败,{当前用户未登录}" + e);
        throw e;
    }
}
